package models

import (
	"encoding/base64"
	"encoding/xml"
	"git.tmuyu.com.cn/beego/util"
	"sort"
	"strconv"
	"strings"
	"time"
)

type Message struct {
	ToUser      string      `json:"touser"`
	TemplateId  string      `json:"template_id"`
	Url         string      `json:"url"`
	Miniprogram Miniprogram `json:"miniprogram"`
	Data        Data        `json:"data"`
}
type Miniprogram struct {
	Appid    string `json:"appid"`
	Pagepath string `json:"pagepath"`
}
type Data struct {
	First    Raw `json:"first"`
	Keyword1 Raw `json:"keyword1"`
	Keyword2 Raw `json:"keyword2"`
	Remark   Raw `json:"remark"`
}

type Raw struct {
	Value string `json:"value"`
	Color string `json:"color"`
}

type SendData struct {
	First    string `json:"first"`
	Keyword1 string `json:"keyword1"`
	Keyword2 string `json:"keyword2"`
	Remark   string `json:"remark"`
	Color    string `json:"color"`
	Code     int    `json:"code"`
	CadreID  string `json:"cadre_id"`
}

type Limits struct {
	Limit int `json:"limit"`
}
type CreatMsg struct {
	SendData
	Openid string `json:"openid"`
}
type Openid struct {
	Openid string `json:"openid"`
}
type Code struct {
	Code string `json:"code"`
}

type Response struct {
	Code    int         `json:"code"`
	Data    interface{} `json:"data"`
	Message string      `json:"message"`
}

// DefaultReply 公众号默认回复
const DefaultReply = "success"

// ReplyHeader 公众号消息回复公共头
type ReplyHeader struct {
	ToUserName   util.CDATA `xml:"ToUserName"`
	FromUserName util.CDATA `xml:"FromUserName"`
	CreateTime   int64      `xml:"CreateTime"`
	MsgType      util.CDATA `xml:"MsgType"`
}

// TextReply 公众号文本回复
type TextReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	Content util.CDATA `xml:"Content"`
}

// ImageReply 公众号图片回复
type ImageReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	Image struct {
		MediaID util.CDATA `xml:"MediaId"` // 通过素材管理接口上传多媒体文件得到 MediaId
	} `xml:"Image"`
}

// VoiceReply 公众号语音回复
type VoiceReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	Voice struct {
		MediaID util.CDATA `xml:"MediaId"` // 通过素材管理接口上传多媒体文件得到 MediaId
	} `xml:"Voice"`
}

// Video 公众号视频回复
type VideoReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	Video struct {
		MediaID     util.CDATA `xml:"MediaId"`               // 通过素材管理接口上传多媒体文件得到 MediaId
		Title       util.CDATA `xml:"Title,omitempty"`       // 视频消息的标题, 可以为空
		Description util.CDATA `xml:"Description,omitempty"` // 视频消息的描述, 可以为空
	} `xml:"Video" json:"Video"`
}

// Music 公众号音乐回复
type MusicReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	Music struct {
		Title        util.CDATA `xml:"Title,omitempty"`       // 音乐标题
		Description  util.CDATA `xml:"Description,omitempty"` // 音乐描述
		MusicURL     util.CDATA `xml:"MusicUrl,omitempty"`    // 音乐链接
		HQMusicURL   util.CDATA `xml:"HQMusicUrl,omitempty"`  // 高质量音乐链接, WIFI环境优先使用该链接播放音乐
		ThumbMediaID util.CDATA `xml:"ThumbMediaId"`          // 通过素材管理接口上传多媒体文件得到 ThumbMediaId
	} `xml:"Music"`
}

// Article 公众号图文
type Article struct {
	Title       util.CDATA `xml:"Title"`       // 图文消息标题
	Description util.CDATA `xml:"Description"` // 图文消息描述
	PicURL      util.CDATA `xml:"PicUrl"`      // 图片链接, 支持JPG, PNG格式, 较好的效果为大图360*200, 小图200*200
	URL         util.CDATA `xml:"Url"`         // 点击图文消息跳转链接
}

// WXPub 微信公众号
type WXPub struct {
	AccountID      string
	AppID          string
	AppSecret      string
	SignToken      string
	EncodingAESKey string
	Client         *util.HTTPClient
}

// Reply 公众号回复
type Reply struct {
	pub    *WXPub
	openid string
}
type ReplyMsg struct {
	XMLName      xml.Name   `xml:"xml"`
	Encrypt      util.CDATA `xml:"Encrypt"`
	MsgSignature util.CDATA `xml:"MsgSignature"`
	TimeStamp    int64      `xml:"TimeStamp"`
	Nonce        util.CDATA `xml:"Nonce"`
}

// Articles 公众号图文回复
type ArticlesReply struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	ArticleCount int        `xml:"ArticleCount"`  // 图文消息个数, 限制为10条以内
	Articles     []*Article `xml:"Articles>item"` // 多条图文消息信息, 默认第一个item为大图, 注意, 如果图文数超过10, 则将会无响应
}

// TransInfo 转发客服账号
type TransInfo struct {
	KfAccount util.CDATA `xml:"KfAccount"`
}

// Transfer2KF 公众号消息转客服
type Transfer2KF struct {
	XMLName xml.Name `xml:"xml"`
	ReplyHeader
	TransInfo *TransInfo `xml:"TransInfo,omitempty"`
}

// Text build wxpub text reply msg
func (r *Reply) Text(content string) ([]byte, error) {
	m := &TextReply{
		ReplyHeader: ReplyHeader{
			ToUserName:   util.CDATA(r.openid),
			FromUserName: util.CDATA(r.pub.AccountID),
			CreateTime:   time.Now().Unix(),
			MsgType:      util.CDATA("text"),
		},
	}

	m.Content = util.CDATA(content)

	b, err := xml.Marshal(m)

	if err != nil {
		return nil, err
	}

	return b, nil
}

func (r *Reply) buildMsg(msgBody []byte) (*ReplyMsg, error) {
	// 消息加密
	//cipherText, err := r.encrypt(msgBody)
	//
	//if err != nil {
	//	return nil, err
	//}

	encrypt := base64.StdEncoding.EncodeToString(msgBody)

	now := time.Now().Unix()
	nonce := util.NonceStr()

	signItems := []string{r.pub.SignToken, strconv.FormatInt(now, 10), nonce, encrypt}

	sort.Strings(signItems)

	msg := &ReplyMsg{
		Encrypt:      util.CDATA(encrypt),
		MsgSignature: util.CDATA(util.SHA1(strings.Join(signItems, ""))),
		TimeStamp:    now,
		Nonce:        util.CDATA(nonce),
	}

	return msg, nil
}
